package fiuba.service.impl;

import java.util.ArrayList;
import java.util.List;

import fiuba.dao.EncuestaDao;
import fiuba.dao.GenericDao;
import fiuba.model.Encuesta;
import fiuba.model.OpcionEncuesta;
import fiuba.model.VotoEncuesta;
import fiuba.service.EncuestaManager;

public class EncuestaManagerImpl extends GenericManagerImpl<Encuesta, Long> implements EncuestaManager{
	private EncuestaDao encuestaDao;
	private GenericDao<VotoEncuesta, Long> votoEncuestaDao;
	private GenericDao<OpcionEncuesta, Long> opcionEncuestaDao;
	
    public EncuestaManagerImpl(EncuestaDao encuestaDao,
    		GenericDao<VotoEncuesta, Long> votoEncuestaDao,
    		GenericDao<OpcionEncuesta, Long> opcionEncuestaDao
    		) {
        super(encuestaDao);
        this.encuestaDao = encuestaDao;
        this.votoEncuestaDao = votoEncuestaDao;
        this.opcionEncuestaDao = opcionEncuestaDao;
    }
    
    // Borra todas las opciones de la encuesta
	public Encuesta quitarOpciones(Encuesta e, String[] seleccionadas){
		List<String> aBorrar = new ArrayList<String>();
		// Obtengo cuales se van a eliminar
		for (OpcionEncuesta o : e.getOpciones()) {
			// Si esta en los seleccionados, no la quito
			boolean quitar = true;
			for (int i = 0; i < seleccionadas.length; i++) {
				if (o.getRespuesta().equals(seleccionadas[i])) quitar = false;
			}
			if (quitar) { 
				aBorrar.add(o.getRespuesta());
			}
		}
		// Elimino los que antes clasifique como "a borrar"
		List<OpcionEncuesta> listaParalela = new ArrayList<OpcionEncuesta>();
		for (OpcionEncuesta o : e.getOpciones()) {
			if (!aBorrar.contains(o.getRespuesta())) {
				listaParalela.add(o);
			}
			else {
				opcionEncuestaDao.remove(o.getId());
			}
		}
		e.setOpciones(listaParalela);
		return e;
	}
	
	public OpcionEncuesta saveOption(OpcionEncuesta op) {
		return this.opcionEncuestaDao.save(op);
	}

	public Encuesta registrarVoto(Encuesta e, String votos, String ip){
		// Si no esta activada o ya se voto desde el ip, devuelvo sin registrar voto 
		if (!e.isActivada()) return e;
		for (VotoEncuesta v : e.getVotos()) {
			if (v.getIp().equals(ip)) {
				return e;
			}
		}
		
		// Agrego el voto
		VotoEncuesta v = new VotoEncuesta();
		v.setEncuesta(e);
		v.setIp(ip);
		v = this.votoEncuestaDao.save(v);
		e.getVotos().add(v);
		
		// Sumo 1 a las opciones votadas
		String[] arrVotos = votos.split(",",-1);
		// para cada opcion, veo si hay voto
		for (OpcionEncuesta o : e.getOpciones()) {
			boolean seVoto = false;
			for (int i = 0; i < arrVotos.length; i++) {
				if (o.getSecuencia().toString().equals(arrVotos[i])) {
					seVoto = true;
				}
			}
			if (seVoto) { // Se la voto => aumentar en 1
				o.setVotos(o.getVotos() + 1);
				this.opcionEncuestaDao.save(o);
			}
		}
		return e;
	}
	
	public String generateHtml(Long id, String ip) {
		Encuesta e = this.encuestaDao.get(id);
		if (!e.isActivada()) return generateHtmlResultados(e);
		// Veo si hay un voto del ip
		for (VotoEncuesta v : e.getVotos()) {
			if (v.getIp().equals(ip)) {
				return generateHtmlResultados(e);
			}
		}
		
		return generateHtmlVotacion(e);
	}
	/*
	 * 
	 *  RELACIONADO CON LA GENERACION DE HTMLS
	 * 
	 */
	private String generateHtmlResultados(Encuesta e) {
		StringBuffer sb = new StringBuffer();
		inicioHtml(sb,e);
		// Variables comunes a utilizar
		String idTabla = "enc_res_" + e.getId();
		String colorResultado = " color='" + e.getColorTexto() + "' ";
		String fontColor = "<FONT COLOR=\"" + e.getColorTexto() + "\">";
		int votosTotales = 0;
		int mayorVoto = 0;
		// Calculo de cantidad de votos
		for (OpcionEncuesta o : e.getOpciones()) {
			votosTotales += o.getVotos();
			if (o.getVotos() > mayorVoto) mayorVoto =  o.getVotos();
		}
		String vectorPorcentajes = "";
		// Tabla con resultados
		sb.append("<table id='").append(idTabla).append("' width='100%'>");
		for (OpcionEncuesta o : e.getOpciones()) {
			// Calculo de porcentaje
			int pct = 0;
			if (votosTotales != 0) pct = Math.round( (o.getVotos() * 100) / votosTotales );
			String colorBarra = e.getColorResultado();
			if (o.getVotos() == mayorVoto) colorBarra = e.getColorResultadoGanador();
			// Escupir html
			sb.append("<tr" + colorResultado + "><td align='left'>" + fontColor).append(o.getRespuesta())
			.append(":</font></td><td align='right'>" + fontColor ).append(pct).append("%</font></td></tr>")
			.append("<tr><td colspan='2'><div class='enc_pct encuestaResultado' style='background-color:")
			.append(colorBarra).append(";'>&nbsp;</div></font></td></tr>");
			/* style='width:")
			.append(pct).append("%;'*/
			// Armar vector porcentajes
			if (!vectorPorcentajes.equals("")) vectorPorcentajes = vectorPorcentajes + ",";
			vectorPorcentajes = vectorPorcentajes + pct;			
		}
		// Fin de tabla
		sb.append("<tr><td colspan='2' align='center'>" + fontColor + "Votos: ")
			.append(votosTotales).append("</font></td></tr>");
		sb.append("</table>")
		.append("</div>");
		// Script para mostrar de forma "linda" los porcentajes
		sb.append("<script language='javascript'>");
		String idVectorProcentajes = "enc_arr_por_" + e.getId();
		sb.append("var " + idVectorProcentajes + " = [" + vectorPorcentajes + "];");
		sb.append("$(document).ready(function(){");
			// Recorro los divs con datos
			sb.append("$('#" + idTabla + " .enc_pct').each(function(i){");
				sb.append("var percentage = " + idVectorProcentajes + "[i];");
				sb.append("$(this).css({width: '0%'}).animate({width: ('' + percentage + '%') }, 'slow'); ");
			sb.append("});");
		sb.append("});");
		sb.append("</script>");
		
		return sb.toString();
	}
	
	// Este HTML es el que se muestra cuando tiene la opcion de votar
	private String generateHtmlVotacion(Encuesta e) {
		StringBuffer sb = new StringBuffer();
		String idBoton = "enc_bot_" + e.getId();
		String idEncuesta = "enc_poll_" + e.getId();
		inicioHtml(sb,e);
		sb.append("<form id='" + idEncuesta + "' action='#' method='post' accept-charset='utf-8'>");
		for (OpcionEncuesta o : e.getOpciones()) {
			String type = (e.getTipo() == 1) ? "radio" : "checkbox";
			String idOption = "opt_" + e.getId() + "_" + o.getSecuencia();
			sb.append("<input type='").append(type)
			.append("' name='poll' value='").append(o.getSecuencia())
			.append("' id='").append(idOption)
			.append("' /><label for='").append(idOption)
			.append("'>&nbsp;").append(o.getRespuesta()).append("</label><br />");
		}
		sb.append("<br /><div style='text-align:center'><input type='submit' id='" + idBoton + "' value='Votar &rarr;' /></div></p>").append("</form>").append("</div>");
		// Script para mostrar de forma "linda" los porcentajes
		sb.append("<script language='javascript'>");
		sb.append("$(document).ready(function(){\n");
			// Recorro los divs con datos
			sb.append("$('#" + idEncuesta + "').submit(function(event){\n");
				sb.append("event.preventDefault();");
				sb.append("var secuencias = '';");
				sb.append("$('#" + idEncuesta + " input:checked, #" + idEncuesta + " input:selected').each(function(){\n");
					sb.append("var nseq = (this.id).split('_')[2];");
					sb.append("if (secuencias != '') secuencias = secuencias + ',';");
					sb.append("secuencias = secuencias + nseq;");
				sb.append("});\n");
				sb.append("$('#" + idBoton + "').attr('disabled','true');\n");
				sb.append("$.getJSON('/votarEncuesta.html',{id:" + e.getId() + ",votos:secuencias,ajax:true,rnd:Math.random()},function(data) {");
					// DE ACA EN ADELANTE, JAVASCRIPT PARA MOSTRAR RESULTADOS
					String idTabla = "enc_res_" + e.getId();
					sb.append("var newHtml = '<table id=\"" + idTabla + "\" width=\"100%\">';\n");
					sb.append("var colorResultado = '';\n");
					sb.append("var fontColor = '';\n");
					sb.append("for (var i = 0; i < data.opciones.length; i++) {\n");
						sb.append("var opcion = data.opciones[i];\n");
						sb.append("var colorBarra = '" + e.getColorResultado() + "';\n");
						sb.append("if (opcion.votos == data.mayorVoto) colorBarra = '" + e.getColorResultadoGanador() + "';\n");
						sb.append("newHtml = newHtml + '<tr><td align=\"left\"><FONT COLOR=\"" + e.getColorTexto() + "\">'\n");
							sb.append("+ opcion.nombre + ':</font></td><td align=\"right\"><FONT COLOR=\"" + e.getColorTexto() + "\">'\n");
							sb.append("+ opcion.porcentaje + '%</font></td></tr>'\n");
							sb.append("+ '<tr><td colspan=\"2\"><div class=\"enc_pct encuestaResultado\" style=\"background-color:'\n");
							sb.append("+ colorBarra + ';\">&nbsp;</div></font></td></tr>';\n");
					sb.append("}\n");
					sb.append("newHtml = newHtml + '<tr><td colspan=\"2\" align=\"center\"><FONT COLOR=\"" + e.getColorTexto() + "\">Votos: '\n");
						sb.append("+ data.votosTotales + '</font></td></tr></table>';\n");
						//sb.append("newHtml = 'CONCHUDO';\n");
						
					sb.append("$('#" + idEncuesta + "').html(newHtml);\n");
					// Animacion
					sb.append("$('#" + idTabla + " .enc_pct').each(function(i){");
						sb.append("var percentage = data.opciones[i].porcentaje;");
						sb.append("$(this).css({width: '0%'}).animate({width: ('' + percentage + '%') }, 'slow'); ");
					sb.append("});");
					
					// FIN JAVASCRIPT PARA MOSTRAR RESULTADOS
				sb.append("}); // getJSON\n");
				sb.append("return false;\n");
			sb.append("});\n");
		sb.append("});\n");
		sb.append("</script>");
		
		return sb.toString();
	}
	
	private void inicioHtml(StringBuffer sb, Encuesta e) {
		sb.append("<div id='poll-container-").append(e.getId()).append("' style='padding:5px;width:90%;text-align:left;");
		if (! e.getColorFondo().equals("")) {
			sb.append("background-color:").append(e.getColorFondo()).append(";");
		}
		if (! e.getColorTexto().equals("")) {
			sb.append("color:").append(e.getColorTexto()).append(";");
		}
		if (! e.getColorBorde().equals("")) {
			sb.append("border: 2px solid ").append(e.getColorBorde()).append(";");
		}
		sb.append("'>");
		sb.append("<p class='encuestaPregunta'");
		if (! e.getColorTitulo().equals("")) {
			sb.append(" style='color:").append(e.getColorTitulo()).append(";'");
		}
		sb.append("><b>").append(e.getPregunta()).append("</b></p>")
		.append("<p>");
		
	}
	
}
